package com.arpa.oms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.arpa.core.web.Result;
import com.arpa.ntocc.common.common.cache.PartyCache;
import com.arpa.ntocc.common.common.exception.ServiceException;
import com.arpa.ntocc.common.common.util.UserUtil;
import com.arpa.oms.domain.dto.OmsReplacedGoodsDTO;
import com.arpa.oms.domain.dto.SaleItemDto;
import com.arpa.oms.domain.entity.OmsReplacedGoods;
import com.arpa.oms.domain.entity.PurchaseItem;
import com.arpa.oms.domain.entity.Sale;
import com.arpa.oms.domain.entity.SaleItem;
import com.arpa.oms.domain.vo.OmsReplacedGoodsVO;
import com.arpa.oms.mapper.OmsReplacedGoodsMapper;
import com.arpa.oms.service.IOmsReplacedGoodsService;
import com.arpa.oms.service.IPurchaseItemService;
import com.arpa.oms.service.ISaleItemService;
import com.arpa.oms.service.ISaleService;
import com.arpa.wms.cache.ShopCache;
import com.arpa.wms.cache.WarehouseCache;
import com.arpa.wms.common.util.UUIDUtil;
import com.arpa.wms.domain.consts.NumConst;
import com.arpa.wms.domain.entity.Goods;
import com.arpa.wms.service.IGoodsService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import net.bytebuddy.implementation.auxiliary.AuxiliaryType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 替换商品信息 服务实现类
 * </p>
 *
 * @author rfwang
 * @since 2021年8月5日
 */
@Service
public class OmsReplacedGoodsServiceImpl extends ServiceImpl<OmsReplacedGoodsMapper, OmsReplacedGoods> implements IOmsReplacedGoodsService {

    @Autowired
    private ISaleItemService saleItemService;
    @Autowired
    private ISaleService saleService;
    @Autowired
    private PartyCache partyCache;
    @Autowired
    private IGoodsService goodsService;
    @Autowired
    private WarehouseCache warehouseCache;
    @Autowired
    private ShopCache shopCache;



    /**
     * 查询列表
     * @param omsReplacedGoodsDTO
     * @return
     */
    @Override
    public List<OmsReplacedGoodsVO> queryList(OmsReplacedGoodsDTO omsReplacedGoodsDTO) {
        return this.baseMapper.queryList(omsReplacedGoodsDTO);
    }

    /**
     * 查询合计,包含总数
     * @param omsReplacedGoodsDTO
     * @return
     */
    @Override
    public OmsReplacedGoodsVO queryListSum(OmsReplacedGoodsDTO omsReplacedGoodsDTO){
        return this.baseMapper.queryListSum(omsReplacedGoodsDTO);
    }

    /**
     * 替换销售商品
     * @param omsReplacedGoodsDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public Result replaceGoods(OmsReplacedGoodsDTO omsReplacedGoodsDTO){
        //1.检验商品
        validateReplaceGoods(omsReplacedGoodsDTO);
        //2.替换商品
        List<String> saleCodes = omsReplacedGoodsDTO.getSaleCodes();
        List<SaleItem> saleItemList = saleItemService.list(new LambdaQueryWrapper<SaleItem>().in(SaleItem::getSaleCode, saleCodes)
                .eq(SaleItem::getGoodCode, omsReplacedGoodsDTO.getOriginalGoodCode()));
        Goods goods = goodsService.getOne(new LambdaQueryWrapper<Goods>().eq(Goods::getGoodCode, omsReplacedGoodsDTO.getReplacedGoodCode())
                .eq(Goods::getShipmentCode,omsReplacedGoodsDTO.getShipmentCode()));
        BigDecimal salePrice = goods.getDeliveryPrice();
        saleItemList.stream().forEach(info -> {
            SaleItem dto = new SaleItem();
            //折扣价格等于替换商品的销售价格减去原商品的销售价格
            BigDecimal discountAmount = salePrice.multiply(info.getActualQuantity()).setScale(goods.getUnitPrecision().intValue(), BigDecimal.ROUND_HALF_UP)
                    .subtract(info.getAmountMoney());
            dto.setId(info.getId());
            dto.setGoodsCode(omsReplacedGoodsDTO.getOriginalGoodCode());
            dto.setGoodsCode(omsReplacedGoodsDTO.getReplacedGoodsCode());
            dto.setGoodCode(omsReplacedGoodsDTO.getReplacedGoodCode());
            dto.setGoodsName(omsReplacedGoodsDTO.getReplacedGoodsName());
            dto.setGoodsBarCode(omsReplacedGoodsDTO.getReplacedGoodsBarCode());
            dto.setDiscountAmount(discountAmount);
            saleItemService.updateById(dto);
        });
        //3.生成替换商品接口
        generateReplaceGoods(omsReplacedGoodsDTO);
        return Result.ok();

    }

    private void validateReplaceGoods(OmsReplacedGoodsDTO omsReplacedGoodsDTO){
        List<String> saleCodes = omsReplacedGoodsDTO.getSaleCodes();
        int totalCount = saleCodes.size();
        if (IterUtil.isEmpty(saleCodes)) {
            throw new ServiceException("所选销售单不能为空，请确认");
        }
        if (StrUtil.isEmpty(omsReplacedGoodsDTO.getOriginalGoodCode())) {
            throw new ServiceException("原商品编码不能为空，请确认");
        }
        if (StrUtil.isEmpty(omsReplacedGoodsDTO.getReplacedGoodCode())) {
            throw new ServiceException("替换商品编码不能为空，请确认");
        }
        int countSale = saleService.count(new LambdaQueryWrapper<Sale>().in(Sale::getCode, saleCodes).eq(Sale::getShopCode, omsReplacedGoodsDTO.getShopCode())
                .eq(Sale::getWarehouseCode, omsReplacedGoodsDTO.getWarehouseCode()).eq(Sale::getShipmentCode, omsReplacedGoodsDTO.getShipmentCode()));
        if (totalCount != countSale) {
            throw new ServiceException("所选订单的店铺或者仓库不一致，请确认");
        }
        int countSaleItem = saleItemService.count(new LambdaQueryWrapper<SaleItem>().in(SaleItem::getSaleCode, saleCodes)
                .eq(SaleItem::getGoodCode, omsReplacedGoodsDTO.getOriginalGoodCode()));
        if (totalCount != countSaleItem) {
            throw new ServiceException("所选订单不包含商品 " + omsReplacedGoodsDTO.getOriginalGoodsName());
        }
    }

    private void generateReplaceGoods(OmsReplacedGoodsDTO omsReplacedGoodsDTO) {
        OmsReplacedGoods omsReplacedGoods = new OmsReplacedGoods();
        BeanUtil.copyProperties(omsReplacedGoodsDTO,omsReplacedGoods);
        omsReplacedGoods.setCode(IdUtil.simpleUUID());
        omsReplacedGoods.setCreatedBy(UserUtil.getCode());
        omsReplacedGoods.setCreatedName(partyCache.translate(UserUtil.getCode()));
        omsReplacedGoods.setModifiedBy(UserUtil.getCode());
        omsReplacedGoods.setModifiedName(partyCache.translate(UserUtil.getCode()));
        omsReplacedGoods.setShopName(shopCache.translate(omsReplacedGoodsDTO.getShopCode()));
        omsReplacedGoods.setWarehouseName(warehouseCache.translate(omsReplacedGoodsDTO.getWarehouseCode()));
        this.save(omsReplacedGoods);
    }
}
